/**
 *    Copyright 2009-2020 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.aapl.interceptor;

import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.executor.statement.StatementHandler;

import java.util.*;

/**
 * 一个静态类，专门用于拦截StatementHandler/ResultSetHandler/ParameterHandler
 * 并使用它们对相关处理器进行增强或修改
 *
 * @author gu
 * @date 2020/4/7 9:40
 */
public class HandlerProcessor {

  private static Set<StatementProcessor> statementProcessors = new LinkedHashSet<>();
  private static Set<ParameterProcessor> parameterProcessors = new LinkedHashSet<>();
  private static Set<ResultSetProcessor> resultSetProcessors = new LinkedHashSet<>();

  static {
    addParameterProcessor(new FieldInjectionProcessor());
    addParameterProcessor(new EnhanceEarlyFieldProcessor());
    addParameterProcessor(new EnhanceEarlyParamProcessor());
    addResultSetProcessor(new EnhanceAfterFieldProcessor());
    addResultSetProcessor(new EnhanceAfterQueryProcessor());
    addStatementProcessor(new RefreshStatementProcessor());
  }

  public static void processStatement(StatementHandler handler) {
    for (StatementProcessor statementProcessor : statementProcessors) {
      statementProcessor.process(handler);
    }
  }

  public static void processParameter(ParameterHandler handler) {
    for (ParameterProcessor parameterProcessor : parameterProcessors) {
      parameterProcessor.process(handler);
    }
  }

  public static void processResultSet(ResultSetHandler handler, List<Object> objs) {
    for (ResultSetProcessor resultSetProcessor : resultSetProcessors) {
      resultSetProcessor.process(handler, objs);
    }
  }

  public static void addStatementProcessor(StatementProcessor processor) {
    statementProcessors.add(processor);
  }

  public static void addParameterProcessor(ParameterProcessor processor) {
    parameterProcessors.add(processor);
  }

  public static void addResultSetProcessor(ResultSetProcessor processor) {
    resultSetProcessors.add(processor);
  }
}
